www.gusucode.com > XerCMS 携云PHP企业建站程序 v2015PHP源码程序 > XerCMS 携云PHP企业建站程序 v2015/XerCMS_v20150724/XerCMS_v20150724/XerCMS/Library/XerCMS_compiler.php
<?php /** * @name XERCMS * @author Arno <XerCMS@163.com> [QQ:1328013] * @version 1.0.0 * @link http://www.XerCMS.com */ !defined('XERCMS') && exit('Access Denied'); class compiler { private $temp = ''; private $html = ''; private $result = ''; private $tplDir = ''; private $currDir = ''; private $cInst = NULL; public $cacheId = ''; public $phpstr = array(); public $embeds = NULL; public $pregVer = NULL; public $data_Id = 0; private $links; public $valName = ''; public function Set($dir,$file,$cacheId = '') { $this->cacheId = empty($cacheId) ? md5($dir.$file) : $cacheId; $this->tplDir = $dir; $this->currDir = dirname($dir.$file).'/'; $this->html = $this->tpl($file); } public function tpl($file) { if($file == NULL) return ''; if(strpos($file,'/') !== false) { $file = $this->tplDir.$file; } else $file = $this->currDir.$file; $file = XERCMS.$file; if(is_file($file)) { return file_get_contents($file); } else throw new TpError($file.' is not exist!'); } public function php($method = 'hide',$data = '') { switch($method) { case 'hide': if(strpos($this->html,'{XERCMS:eval}') !== false && strpos($this->html,'{end:eval}') !== false) { $this->html = $this->preg('/{XERCMS\:eval}(.*?){end\:eval}/is',function ($match){return X::$compiler->php('code',$match[1]);},$this->html); } break; case 'show': foreach($this->phpstr as $k=>$v) { $rep['{php#'.$k.'}{/php}'] = '<?php '.$v.' ?>'; } if(empty($rep)) return; $this->html = strtr($this->html,$rep); break; case 'code': if(empty($data)) return ''; $key = count($this->phpstr); $this->phpstr[$key] = $data; return '{php#'.$key.'}{/php}'; break; } } private function sub() { $max = 5; $hasSub = strpos($this->html,'{XERCMS#'); while($hasSub !== false && $max > 0) { $this->html = $this->preg('/{XERCMS\#([a-z0-9\_\/\.]+)}/is',function($match){return X::$compiler->tpl($match[1]);},$this->html); $hasSub = strpos($this->html,'{XERCMS#'); $max--; } } public function ads() { $this->html = preg_replace_callback('/{XERCMS\$G\[ads\]\[([0-9]+)\]}/is',function($match){return '<?php echo ads('.$match[1].');?>';},$this->html); } public function quote($str) { return $this->preg('/\[([a-zA-Z0-9\_]+)\]/','[\'\\1\']',$str,false); } public function v() { $this->html = $this->preg('/{XERCMS\$([a-zA-Z0-9\$\[\]\_\'\.\"]+)}/is',function($match){return '<?php echo $'.trim(preg_replace('/\[([a-zA-Z0-9\_]+)\]/','[\'\\1\']',$match[1])).';?>';},$this->html); } public function txt() { $this->html = $this->preg('/{XERCMS\@([a-zA-Z0-9\$\[\]\_\'\"]+)}/is',function($match){return '<?php echo htmlchars($'.trim(preg_replace('/\[([a-zA-Z0-9\_]+)\]/','[\'\\1\']',$match[1])).');?>';},$this->html); } public function values() { $this->html = $this->preg('/{XERCMS\&([a-zA-Z0-9\_]+)\(([a-zA-Z0-9\[\]\$\_\'\"]+)\)}/is',function($match){return '<?php echo sVar(\''.$match[1].'\','.(strpos($match[2],'$') === 0 ? '' : '$').X::$compiler->quote($match[2]).'); ?>';},$this->html); } public function i() { if(strpos($this->html,'{XERCMS:if') !== false) { $this->html = $this->preg('/{XERCMS:if ([^\}]*?)}/is',function($match){return '<?php if ('.X::$compiler->preg('/\[([a-zA-Z0-9\_]+)\]/','[\'\\1\']',$match[1],false).') { ?>';},$this->html); $this->html = strtr($this->html,array('{end:if}'=>'<?php } ?>')); if(strpos($this->html,'{XERCMS:else}') !== false) { $this->html = strtr($this->html,array('{XERCMS:else}'=>'<?php } else { ?>')); } if(strpos($this->html,'{XERCMS:elseif') !== false) { $this->html = $this->preg('/{XERCMS:elseif ([^\}]*?)}/is',function($match){return '<?php } else if ('.X::$compiler->quote($match[1]).') { ?>';},$this->html); } } } public function fun($method = '',$name = '',$params = '') { switch($method) { case 'php': $params = strtr(trim($params),array(']'=>'\']','['=>'[\'')); return '<?php echo '.$name.'('.$params.');?>'; break; default: if(strpos($this->html,'{XERCMS!') !== false) $this->html = $this->preg('/{XERCMS!([a-z0-9\_]+)\((.*?)\)}/is',function($match){return X::$compiler->fun('php',$match[1],$match[2]);},$this->html); break; } } private function param($attr) { if(!is_array($attr) || count($attr) !== 2) { return array(); } $ret = array(); foreach($attr[1] as $k=>$v) { $ret[$v] = isset($attr[2][$k]) ? $attr[2][$k] : ''; } return $ret; } private function vars($params) { foreach($params as $k=>$str) { $str = trim($str); $params[$k] = strpos($str,'&') === 0 ? '$'.trim(strtr(preg_replace('/\[([a-zA-Z0-9\_]+)\]/','[\'\\1\']',$str),array('&'=>''))) : (strpos($str,'$') === 0 ? $this->quote($str) : $str); } return $params; } public function arr($param,$html) { return '<?php foreach($'.preg_replace('/\[([a-zA-Z0-9\_]+)\]/','[\'\\1\']',$param['name']).' as '.(isset($param['index']) ? '$'.$param['index'].'=>' : '').'$'.$param['data'].') { ?>'.$html.'<?php } ?>'; } public function page($param,$html,$layer) { if(empty($param['data']) || empty($param['total']) || empty($param['current']) || empty($param['range'])) return $html; $php = '<?php ';$param['range'] = (int)$param['range']; $php .= '$'.$param['data'].'[\'URL\'] = '.((strpos($param['url'],'$') === 0) ? $param['url'] : '\''.$param['url'].'\'').';'; $php .= '$'.$param['data'].'[\'total\'] = '.((strpos($param['total'],'$') === 0) ? $param['total'] : '\''.$param['total'].'\'').';'; $php .= '$'.$param['data'].'[\'current\'] = '.((strpos($param['current'],'$') === 0) ? $param['current'] : '\''.$param['current'].'\'').';'; $php .= '$'.$param['data'].'[\'pre\'] = '.$param['current'].' < 1 ? 1 : ('.$param['current'].' - 1);'; $php .= '$'.$param['data'].'[\'next\'] = '.$param['current'].' > '.$param['total'].' ? '.$param['total'].' : ('.$param['current'].' + 1);'; $php .= '$'.$param['data'].'[\'preURL\'] = strtr($'.$param['data'].'[\'URL\'],array(\'[page]\'=>$'.$param['data'].'[\'pre\']));'; $php .= '$'.$param['data'].'[\'nextURL\'] = strtr($'.$param['data'].'[\'URL\'],array(\'[page]\'=>$'.$param['data'].'[\'next\']));'; $php .= '$'.$param['data'].'[\'totalURL\'] = strtr($'.$param['data'].'[\'URL\'],array(\'[page]\'=>$'.$param['data'].'[\'total\']));'; $php .= '$'.$param['data'].'[\'currentURL\'] = strtr($'.$param['data'].'[\'URL\'],array(\'[page]\'=>$'.$param['data'].'[\'current\']));'; $php .= '$'.$param['data'].'[\'pages\'] = pages($'.$param['data'].'[\'total\'],$'.$param['data'].'[\'current\'],'.$param['range'].',$'.$param['data'].'[\'URL\']);'; $php .= ' ?>'.$html; return $php; } public function table($param,$html,$layer) { if(empty($param['from'])) return 'table is empty!'; if(isset($param['cache'])) { $cache = (int)$param['cache']; unset($param['cache']); } $sql = 'SELECT '.(isset($param['field']) && !empty($param['field']) ? $param['field'] : ' * ').' FROM '.$param['from']; $sql .= isset($param['left']) ? ' LEFT JOIN '.$param['left'] : '';$limit = isset($param['limit']) && !empty($param['limit']) ? ' LIMIT '.$param['limit'] : ' LIMIT 15 '; if(isset($param['index'])) { $key = '$'.$param['index'].'=>'; unset($param['index']); } else $key = ''; if(isset($param['data'])) { $value = '$'.$param['data']; unset($param['data']); } else $value = '$val'; unset($param['field'],$param['left'],$param['from'],$param['limit'],$param['data'],$param['index']); foreach($param as $k=>$v) { $where[] = '`'.trim($k).'` = '.(strpos($v,'$') === 0 ? '\'.'.$v.'.\'' : '\''.$v.'\''); } if(!empty($where)) { $where = ' WHERE '.implode(' AND ',$where); } else $where = ''; $sql .= $where.$limit; return '<?php $data_'.$layer.' = '.(isset($cache) ? 'Cache::fetchSql(\''.$sql.'\','.$cache.')' : 'DB::fetch_all(\''.$sql.'\')').';foreach($data_'.$layer.' as '.$key.$value.') { ?>'.$html.'<?php } ?>'; } public function data($param,$html,$layer) { $ret = ''; if(isset($param['cache'])) { $cache = (int)$param['cache']; unset($param['cache']); } if(isset($param['id'])) { $data_select = DB::result('SELECT * FROM XERCMS_select_data WHERE id = \''.(int)$param['id'].'\''); if(isset($data_select['state']) && $data_select['state'] == 0) { if(preg_match_all('/{XERCMS\$([0-9a-z\_]+)}/i',$data_select['sql'],$match)) { foreach($match[1] as $v) { if(!isset($param[$v])) { return 'Param Error!'; } } unset($param['id']);$repl = array(); foreach($param as $k=>$v) { $repl['{XERCMS$'.$k.'}'] = $v; } $data_select['sql'] = strtr($data_select['sql'],$repl); } $this->data_Id++; if($data_select['format'] == 1 ) { return '<?php echo json_encode('.(isset($cache) ? 'Cache::fetchSql(\''.addslashes($data_select['sql']).'\','.$cache.')' : 'DB::fetch_all(\''.addslashes($data_select['sql']).'\')').');?>'; } else { $name = 'data_sql_'.$this->data_Id; return '<?php $'.$name.' = '.(isset($cache) ? 'Cache::fetchSql(\''.addslashes($data_select['sql']).'\','.$cache.')' : 'DB::fetch_all(\''.addslashes($data_select['sql']).'\')').';?>'.strtr($data_select['template'],array('name="__name__"'=>'name="'.$name.'"')); } } } return $ret; } private function link($param,$html,$layer) { if(empty(X::$CONFIG['#links'])) { X::$CONFIG['#links'] = ini('links/'.X::$CONFIG['urlmode']); } if(!isset($param['rule']) || empty($param['rule'])) { return '#'; } if(isset(X::$CONFIG['#links'][$param['rule']])) { if(empty($html)) { return $this->preg('/\{([0-9a-zA-Z\_]+)\}/',function($match){return '';},X::$CONFIG['#links'][$param['rule']]); } else { X::$compiler->valName = trim($html); return $this->preg('/\{([0-9a-zA-Z\_]+)\}/',function($match){return '<?php echo urlParam(\''.$match[1].'\',$'.X::$compiler->valName.','.(X::$CONFIG['urlmode'] == 'dynamic' ? 1 : 0).');?>';},X::$CONFIG['#links'][$param['rule']]); } } else return '#'; } public function tag($name,$param,$html) { if($name == 'embed') return $this->embed($html); if(preg_match_all('/([a-zA-Z0-9]+)=[\'"]([^\'"]+)[\'"]/',$param,$attr)) {//echo $param;print_r($attr); unset($attr[0]);$param = $this->vars($this->param($attr)); } else $param = array(); $html = stripslashes($html); $name = str_replace('#','',$name,$layer); if(!empty($name)) { if($name == 'array') return $this->arr($param,$html); if($name == 'table') return $this->table($param,$html,$layer); if($name == 'page') return $this->page($param,$html,$layer); if($name == 'data') return $this->data($param,$html,$layer); if($name == 'link') return $this->link($param,$html,$layer); /*if($name == 'sql') return $this->sql($attr).$html.'<?php } ?>';*/ global $XERCMS;$CLASS = 'XERCMS_TAG_'.strtoupper($name); if(isset($XERCMS[$CLASS]) == false) { $TagFile = '';$param['name'] = isset($param['name']) ? $param['name'] : $name; if($name == 'plugin') { $TagFile = XERCMS.'XerCMS/Plugins/'.$param['name'].'/XerCMS_TAG_'.$param['name'].'.php'; } else { $TagFile = XERCMS.'XerCMS/Modules/'.$name.'/tag/XerCMS_'.$param['name'].'.php'; } //echo XERCMS.$TagFile; if(is_file($TagFile) === false) { $TagFile = XERCMS.'XerCMS/Utils/tag/XerCMS_'.$name.'.php'; //echo $TagFile;exit; if(is_file($TagFile) === false) { return 'TAG['.$name.'] is not exits!'; } } X::import($TagFile,null); $XERCMS[$CLASS] = new $CLASS(); } $method = isset($param['method']) && !empty($param['method']) ? $param['method'] : $name; if(method_exists($XERCMS[$CLASS],$method)) { return $XERCMS[$CLASS]->$method($param,$html,$layer); } else return 'TAG['.$name.'] METHOD['.$method.'] is not exits!'; } return 'Unknown TAG!'; } public function el() { while(preg_match('/{XERCMS:([a-z0-9\#]+)([^\}]*?)}(.*?){end:\\1}/is',$this->html)) { $this->html = $this->preg('/{XERCMS:([a-z0-9\#]+)([^\}]*?)}(.*?){end:\\1}/is',function($match){return X::$compiler->tag($match[1],$match[2],$match[3]);},$this->html); } } private function embed($name) { if($this->embeds === NULL) $this->embeds = ini('embed'); if(isset($this->embeds[$name]) == false) return 'No embed!'; $data = Cache::fetchSql('SELECT * FROM xercms_embed_template WHERE name = \''.$name.'\'',0); $ret = ''; foreach($data as $v) { $ret .= '<?php embed('.AtoS($v).'); ?>'; } return $ret; } public function preg($pattern,$replacement,$subject,$eval = true) { if(!$eval) return preg_replace($pattern,$replacement,$subject); if(function_exists('preg_replace_callback')) { return preg_replace_callback($pattern,$replacement,$subject); } else { if(preg_match_all($pattern,$subject,$match)) { $max = count($match); foreach($match[0] as $k=>$v) { $temp[$k][0] = $v;//,$match[1][$k]); for($i = 1;$i<$max;$i++) { $temp[$k][$i] = $match[$i][$k]; } } //print_R($temp); foreach($temp as $k=>$v) { $result = $replacement($v); $subject = substr_replace($subject,$result,strpos($subject,$v[0]),strlen($v[0])); } } return $subject; } } public function file($dir = 'template') { static $header = '<?php !defined(\'XERCMS\') && exit(\'Access Denied\');$G = &X::$G; ?>'; return $this->cache($dir,$this->cacheId,$header.$this->html); } public function cache($dir,$file,$data) { if($this->cInst == NULL) { X::import('cache'); $this->cInst = new cache(); $this->cInst->Set(INC.'Caches/'); } $this->cInst->push($dir.'/'.$file,$data); return $this->cInst->file; } public function version() { $this->html = strtr($this->html,array('{VERSION}'=>'Powered by <a href="http://www.XERCMS.com" target="_blank">XerCMS</a>')); } public function sparse($html,$return = false) { $this->html = $html;$this->values(); $this->i();$this->v();$this->txt();$this->el(); return $return ? $this->html : null; } public function parse() { $this->sub(); $this->php('hide');$this->ads(); $this->i();$this->el(); $this->values(); $this->v();$this->txt(); $this->version(); $this->fun(); $this->php('show'); } } ?>